﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using FitnessDiary.Domain.Entities;
using FitnessDiary.WebUI.Models;
using FitnessDiary.Domain.Concrete;
using FitnessDiary.Domain.Abstract;
using FitnessDiary.WebUI.Account;
using FitnessDiary.WebUI.Filters;
using FitnessDiary.WebUI.ControllerHelpers;

namespace FitnessDiary.WebUI.Controllers
{
	[InitializeSimpleMembership]
	[Authorize]
	public class StatController : Controller
	{
		private IFitnessDiaryRepository repository;
		private IUserProvider account;

		public StatController(IFitnessDiaryRepository repository, IUserProvider account)
		{
			this.repository = repository;
			this.account = account;
		}

		public ActionResult Index(int id)
		{
			Stat stat = repository.Stats.Where(s => s.Id == id).Where(s => s.UserId == account.UserId).FirstOrDefault();
			stat.Quantities = repository.Quantities.Where(q => q.Stat.Id == id).ToList();
			if (stat == null)
			{
				return HttpNotFound();
			}
			return View(stat);
		}

		public ActionResult List()
		{
			List<Stat> model = repository.Stats.Where(s => s.UserId == account.UserId).ToList();
			return View(model);
		}

		public ActionResult Create()
		{
			ViewData["UnitList"] = new SelectList(repository.Units, "Id", "Name");
			return View(new Stat());
		}

		[HttpPost]
		public ActionResult Create(Stat stat, string quantityButton)
		{
			if (quantityButton == "add")
			{
				ModelState.Clear();
				if (stat.Quantities == null)
				{
					stat.Quantities = new List<Quantity>();
				}
				stat.Quantities.Add(new Quantity());
				ViewBag.RemoveButton = "show";
				ViewData["UnitList"] = new SelectList(repository.Units, "Id", "Name");
				return View(stat);
			}
			else if (quantityButton == "remove")
			{
				ModelState.Clear();
				if (stat.Quantities != null)
				{
					stat.Quantities.Remove(stat.Quantities.LastOrDefault());
				}
				if (stat.Quantities.Count > 0)
				{
					ViewBag.RemoveButton = "show";
				}
				ViewData["UnitList"] = new SelectList(repository.Units, "Id", "Name");
				return View(stat);
			}
			if (ModelState.IsValid)
			{
				stat.UserId = account.UserId;
				repository.SaveStat(stat);
				return RedirectToAction("List");
			}
			if (stat.Quantities != null)
			{
				ViewBag.RemoveButton = "show";
			}
			ViewData["UnitList"] = new SelectList(repository.Units, "Id", "Name");
			return View(stat);
		}

		public ActionResult Edit(int stat)
		{
			Stat model = repository.Stats.Where(s => s.Id == stat).Where(s => s.UserId == account.UserId).FirstOrDefault();
			if (model == null)
			{
				return HttpNotFound();
			}
			model.Quantities = repository.Quantities.Where(q => q.Stat.Id == model.Id).ToList();
			ViewData["UnitList"] = new SelectList(repository.Units, "Id", "Name");
			return View(model);
		}

		[HttpPost]
		public ActionResult Edit(Stat stat)
		{
			if (ModelState.IsValid)
			{
				stat.UserId = account.UserId;
				repository.UpdateStat(stat);
				return RedirectToAction("List");
			}
			ViewData["UnitList"] = new SelectList(repository.Units, "Id", "Name");
			return View(stat);
		}

		public ActionResult Delete(int stat)
		{
			Stat model = repository.Stats.Where(s => s.Id == stat).Where(s => s.UserId == account.UserId).FirstOrDefault();
			if (model == null)
			{
				return HttpNotFound();
			}
			return View(model);
		}

		[HttpPost, ActionName("Delete")]
		public ActionResult DeleteConfirmed(int stat)
		{
			Stat model = repository.Stats.Where(s => s.Id == stat).Where(s => s.UserId == account.UserId).FirstOrDefault();
			if (model == null)
			{
				return HttpNotFound();
			}
			model.Hits = repository.Hits.Where(h => h.Stat.Id == stat).ToList();
			model.Quantities = repository.Quantities.Where(q => q.Stat.Id == stat).ToList();
			foreach (Hit hit in model.Hits)
			{
				hit.HitComponents = repository.HitComponents.Where(h => h.Hit.Id == hit.Id).ToList();
			}
			repository.DeleteStat(model);
			return RedirectToAction("Index", "Diary");
		}

		public ActionResult Chart(int id)
		{
			ChartModel model = new ChartModel();
			List<Hit> hits = repository.Hits.Where(h => h.Stat.Id == id).Where(h => h.Stat.UserId == account.UserId).OrderBy(h => h.Date).ToList();
			if (hits.Count < 1)
			{
				return View("NoChart");
			}
			int maxValue = 0;
			foreach (Hit hit in hits)
			{
				hit.HitComponents = repository.HitComponents.Where(h => h.Hit.Id == hit.Id).Where(h => h.Hit.Stat.UserId == account.UserId).ToList();
				hit.Stat.Quantities = repository.Quantities.Where(q => q.Stat.Id == id).Where(q => q.Stat.UserId == account.UserId).ToList();
				foreach (HitComponent hitComponent in hit.HitComponents)
				{
					if (hitComponent.Amount > maxValue)
						maxValue = (int)Math.Ceiling(hitComponent.Amount);
				}
			}
			model.Hits = hits;
			model.BeginDate = model.Hits.First().Date;
			model.EndDate = model.Hits.Last().Date;
			model.Today = DiaryHelper.Today(tzCookieValue());
			model.StatName = repository.Stats.Where(s => s.Id == id).FirstOrDefault().Name;
			model.NumberOfSeries = model.Hits.First().HitComponents.Count;
			model.Max = maxValue;
			return View(model);
		}

		protected override void Dispose(bool disposing)
		{
			repository.Dispose();
			base.Dispose(disposing);
		}

		public string tzCookieValue()
		{
			string cookieKey = "timezoneoffset";
			if (Request.Cookies[cookieKey] != null)
			{
				return Request.Cookies[cookieKey].Value;
			}
			else
			{
				return "0";
			}
		}
	}
}